package it.ionize;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import net.sourceforge.squirrel_sql.client.IApplication;
import net.sourceforge.squirrel_sql.client.session.ISession;
import net.sourceforge.squirrel_sql.fw.sql.ISQLConnection;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;

public class BlobExtractorLogic {
	

	private static ILogger s_log = LoggerController.createLogger(BlobExtractorLogic.class);

	private JComboBox blobFieldsComboBox;
	private JComboBox outputFormatComboBox1;
	private JComboBox outputFormatComboBox2;
	private JTextField outputFormatText;
	private JTextField outputPathText;
	private JButton outputPathButton;
	private JButton exportButton;

	private List<String> blobFields;
	private List<String> allFields;
	private IApplication app;
	private String sql;

	public void setBlobFieldsComboBox(JComboBox blobFieldsComboBox) {
		this.blobFieldsComboBox = blobFieldsComboBox;
	}

	public void setOutputFormatComboBox1(JComboBox outputFormatComboBox1) {
		this.outputFormatComboBox1 = outputFormatComboBox1;
	}

	public void setOutputFormatComboBox2(JComboBox outputFormatComboBox2) {
		this.outputFormatComboBox2 = outputFormatComboBox2;
	}

	public void setOutputFormatText(JTextField outputFormatText) {
		this.outputFormatText = outputFormatText;
	}

	public void setOutputPathText(JTextField outputPathText) {
		this.outputPathText = outputPathText;
	}

	public void setOutputPathButton(JButton outputPathButton) {
		this.outputPathButton = outputPathButton;
	}

	public void setExportButton(JButton exportButton) {
		this.exportButton = exportButton;
	}

	public BlobExtractorLogic(List<String> blobFields, List<String> allFields, IApplication app, String sql) {
		this.allFields = allFields;
		this.blobFields = blobFields;
		this.app = app;
		this.sql = sql;
	}

	public void initComponents() {
		this.outputPathText.setEditable(false);

		if (this.allFields != null) {
			this.outputFormatComboBox1.addItem("");
			for (String field : this.allFields) {

				this.outputFormatComboBox1.addItem(field);
			}

			this.outputFormatComboBox2.addItem("");
			for (String field : this.allFields) {

				this.outputFormatComboBox2.addItem(field);
			}
		}

		if (this.blobFields != null) {
			for (String field : this.blobFields) {

				this.blobFieldsComboBox.addItem(field);
			}
		}

		this.exportButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionPerformedExportButton(arg0);
			}
		});

		this.outputPathButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionPerformedPathSelectButton(arg0);
			}
		});

	}

	private void actionPerformedPathSelectButton(ActionEvent arg0) {
		final JFileChooser fc = new JFileChooser();
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int returnVal = fc.showOpenDialog(null);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			this.outputPathText.setText(file.getAbsolutePath());
		}
	}

	private void actionPerformedExportButton(ActionEvent arg0) {
		
		
		ISession session = this.app.getSessionManager().getActiveSession();

		String lobFieldName = (String) this.blobFieldsComboBox.getSelectedItem();

		String outputFormatCombo1Value = (String) this.outputFormatComboBox1.getSelectedItem();
		String outputFormatCombo2Value = (String) this.outputFormatComboBox2.getSelectedItem();

		ISQLConnection connection = session.getSQLConnection();
		PreparedStatement statement = null;

		
		try {
			statement = connection.prepareStatement(sql);
			ResultSet resultSet = statement.executeQuery();
			
			int successFile=0;

			while (resultSet.next()) {
				InputStream lobStream = resultSet.getBinaryStream(lobFieldName);

				//calcolo nome file
				String fileName = "";
				if(!outputFormatCombo1Value.isEmpty() && !"".equals(outputFormatCombo1Value.trim()))
				{
					s_log.debug("combo1Value:"+resultSet.getObject(outputFormatCombo1Value).toString());
					fileName += resultSet.getObject(outputFormatCombo1Value).toString()+"_";
				}
				

				if(!outputFormatCombo2Value.isEmpty() && !"".equals(outputFormatCombo2Value.trim()))
				{
					s_log.debug("combo2Value:"+resultSet.getObject(outputFormatCombo2Value).toString());
					fileName += resultSet.getObject(outputFormatCombo2Value).toString()+"_";
				}
				
				fileName += (this.outputFormatText.getText().isEmpty() || "".equals(this.outputFormatText.getText()) ? "" : this.outputFormatText.getText());

				s_log.debug("filename:"+fileName);
				
				try {
//	                FileWriter fw= new FileWriter(this.outputPathText+File.separator+fileName);
	                OutputStream out = new FileOutputStream(this.outputPathText.getText()+File.separator+fileName);

					s_log.debug("fullpath:"+this.outputPathText+File.separator+fileName);
	                
	            	int read = 0;
	            	byte[] bytes = new byte[1024];
	             
	            	while ((read = lobStream.read(bytes)) != -1) {
	            		out.write(bytes, 0, read);
	            	}
	             
	            	lobStream.close();
	            	out.flush();
	            	out.close();
	            	
	            	successFile++;
	            	
	            	
                } catch (IOException e) {
                	app.showErrorDialog("Cannot create/write on output file: "+fileName,e);
                }

			}
			

    		JOptionPane.showMessageDialog(exportButton, "Export of "+successFile+" completed successfully.");
		} catch (SQLException e) {
        	app.showErrorDialog("Sql error: ",e);

		} finally {
			try {
				if (statement != null) {
					statement.close();
				}
			} catch (SQLException e) {
				//impossibile chiude lo statement?
			}
		}

	}
}
